package com.liu.share.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author liucongcong
 * @date 2018/10/29
 */
public class DateUtil {

    public static final String SP1 = "yyyy-MM-dd HH:mm:ss";
    public static final String SP2 = "yyyyMMddHHmmss";
    public static final String SP3 = "yyyy-MM-dd";
    public static final String SP4 = "yyyyMMdd";
    public static final String SP5 = "yyyy-MM";
    public static final String SP6 = "yyyy年MM月dd日";

    /**
     * 将一种时间格式转换成另一种时间格式
     * @param time   时间
     * @param formatStrBefore  时间格式
     * @param formatStrAfter   目标时间格式
     * @return
     * @throws ParseException
     */
    public static String parseTime(String time, String formatStrBefore, String formatStrAfter) throws ParseException {
        SimpleDateFormat bfSp = new SimpleDateFormat(formatStrBefore);
        SimpleDateFormat afSp = new SimpleDateFormat(formatStrAfter);
        return afSp.format(bfSp.parse(time));
    }

    /**将Date转换成指定格式的时间
     *
     * @param date            日期(Date格式)
     * @param formatStrAfter  目标时间格式
     * @return
     * @throws ParseException
     */
    public static String parseTime(Date date, String formatStrAfter) {
        SimpleDateFormat afSp = new SimpleDateFormat(formatStrAfter);
        return afSp.format(date);
    }

    /**
     * 比较另个时间的大小
     * @param time1
     * @param time2
     * @param formatStr
     * @return  1：time1小于time2  0:time1等于time2 -1:time1大于time2
     * @throws ParseException
     */
    public static int compareTime(String time1, String time2, String formatStr) throws ParseException {
        SimpleDateFormat sp = new SimpleDateFormat(formatStr);
        Date date1 = sp.parse(time1);
        Date date2 = sp.parse(time2);
        if (date1.before(date2)) {
            return 1;
        } else {
            return date1.after(date2) ? -1 : 0;
        }
    }

    /**
     * 获取当前指定格式的日期
     * @param formatStr
     * @return
     */
    public static String getCurrentTime(String formatStr) {
        SimpleDateFormat sp = new SimpleDateFormat(formatStr);
        return sp.format(new Date());
    }


    /**
     * 获取当前日期的前后几天，前后几月，前后几年
     * @param field    单位标识：年，月  Calendar.YEAR, Calendar.MONTH ,Calendar.DAY_OF_YEAR,Calendar.HOUR
     * @param amount   数量：几年，几个月，几周
     * @param formatStr  时间格式
     * @return
     */
    public static String getTimeAfter(int field, int amount, String formatStr) {
        Calendar cal = Calendar.getInstance();
        cal.add(field, amount);
        SimpleDateFormat sp = new SimpleDateFormat(formatStr);
        return sp.format(cal.getTime());
    }

    /**
     * 获取当月第一天
     * @param formatStr
     * @return
     */
    public static String getFirstDayOfMonth(String formatStr) {
        SimpleDateFormat sp = new SimpleDateFormat(formatStr);
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        return sp.format(calendar.getTime());
    }

    /**
     * 获取某天的最后时刻
     * @param date
     * @return
     */
    public static Date getEndOfTheDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(11, 23);
        cal.set(12, 59);
        cal.set(13, 59);
        cal.set(14, 999);
        return cal.getTime();
    }

    /**
     * 获取某天的开始时刻
     * @param date
     * @return
     */
    public static Date getStartOfTheDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    /**
     * 判断两个日期是不是同一天
     * @param d1
     * @param d2
     * @return
     */
    public static boolean isSameDay(Date d1, Date d2) {
        return getStartOfTheDay(d1).getTime() == getStartOfTheDay(d2).getTime();
    }

    /**
     * 获取多少天之前
     * @param date
     * @param diff
     * @return
     */
    public static Date getDateBefore(Date date, int diff) {
        if (date == null) {
            return null;
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(5, calendar.get(5) - diff);
            return calendar.getTime();
        }
    }

    /**
     * 获取多少天之后
     * @param date
     * @param diff
     * @return
     */
    public static Date getDateAfter(Date date, int diff) {
        if (date == null) {
            return null;
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(5, calendar.get(5) + diff);
            return calendar.getTime();
        }
    }

    /**
     * 计算两个日期之间相差多少天
     * @param dateFrom
     * @param dateTo
     * @return
     */
    public static Integer getDiffDays(Date dateFrom, Date dateTo) {
        if (dateFrom != null && dateTo != null) {
            if (dateFrom.after(dateTo)) {
                Date dateTmp = dateFrom;
                dateFrom = dateTo;
                dateTo = dateTmp;
            }

            Calendar calFrom = Calendar.getInstance();
            calFrom.setTime(dateFrom);
            Calendar calTo = Calendar.getInstance();
            calTo.setTime(dateTo);
            int dayFrom = calFrom.get(6);
            int dayTo = calTo.get(6);
            int yearFrom = calFrom.get(1);
            int yearTo = calTo.get(1);
            int diff = dayTo - dayFrom;
            if (yearFrom != yearTo) {
                for(int i = yearFrom; i < yearTo; ++i) {
                    if ((i % 4 != 0 || i % 100 == 0) && i % 400 != 0) {
                        diff += 365;
                    } else {
                        diff += 366;
                    }
                }
            }
            return diff;
        } else {
            return null;
        }
    }

    public static void main(String[] args) {
        System.out.println(new Date());  //Mon Oct 29 10:38:05 CST 2018

        //将Date格式的时间转换成指定格式的时间
        String date = DateUtil.parseTime(new Date(),DateUtil.SP1);
        System.out.println(date);

        //将时间从一种格式转成另一种格式
        try {
            String date2 =DateUtil.parseTime("2018-10-30 11:04:03",DateUtil.SP1,DateUtil.SP6);
            System.out.println(date2);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //比较指定格式的时间
        try {
            int result = DateUtil.compareTime("2018-10-30 11:04:07","2018-10-30 11:04:03",DateUtil.SP1);
            System.out.println(result);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //获取当前时间（指定时间格式）
        System.out.println(DateUtil.getCurrentTime(DateUtil.SP1));

        //获取当前日期的前后几年，几月，几周，几天，几小时，几分钟等等
        System.out.println(DateUtil.getTimeAfter(Calendar.MONTH,6,DateUtil.SP1));
        System.out.println(DateUtil.getTimeAfter(Calendar.DAY_OF_YEAR,2,DateUtil.SP1));

        //获取当月第一天
        System.out.println(DateUtil.getFirstDayOfMonth(DateUtil.SP1));

        //判断两个日期是不是同一天
        System.out.println(DateUtil.isSameDay(new Date(),new Date()));

        //计算两个日期之间间隔多少天
        System.out.println(DateUtil.getDiffDays(new Date(),DateUtil.getDateBefore(new Date(),5)));

    }

}
